package sharewithus.content.dao.cacheimpl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.GetsResponse;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.transcoders.CachedData;
import net.rubyeye.xmemcached.transcoders.PrimitiveTypeTranscoder;
import net.rubyeye.xmemcached.transcoders.Transcoder;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;

import sharewithus.content.dao.IFeedCache;
import sharewithus.content.dao.cacheimpl.encoder.BeanEncoder;
import sharewithus.content.dto.Feed;

public class FeedCacheImpl implements IFeedCache {


	private static int SPECIAL_BYTEARRAY = (8 << 8);

	private static final int EXPIRE_TIME = 60 * 60 * 24 * 30;

	private Transcoder<Feed> transcoder = new FeedTranscoder();

	@Autowired
	private MemcachedClient memcachedClient;

	@Autowired
	private BeanEncoder<Feed> feedEncoder;

	public void saveFeed(Feed feed) {

		try {
			memcachedClient
					.add(feed.getFeedId(), EXPIRE_TIME, feed, transcoder);
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public Feed getFeedById(String feedId) {
		Feed cachedFeed = null;
		try {
			cachedFeed = memcachedClient.get(feedId, transcoder);
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return cachedFeed;
	}

	public Map<String, GetsResponse<Feed>> getFeedbyIds(List<String> feedIds) {
		Map<String, GetsResponse<Feed>> cachedFeeds = new HashMap<String, GetsResponse<Feed>>();
		try {
			cachedFeeds = memcachedClient.gets(feedIds, transcoder);
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return cachedFeeds;
	}


	/**
	 * Transcoder for Feed
	 * 
	 * @author Bruce Wang
	 * 
	 */
	private class FeedTranscoder extends PrimitiveTypeTranscoder<Feed>
			implements Transcoder<Feed> {
		ObjectMapper mapper = new ObjectMapper();

		public CachedData encode(Feed feed) {
			byte[] b = null;
			try {
				b = mapper.writeValueAsBytes(feed);
			} catch (JsonGenerationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JsonMappingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return new CachedData(SPECIAL_BYTEARRAY, b);
		}

		public Feed decode(CachedData d) {
			if (SPECIAL_BYTEARRAY == d.getFlag()) {
				Feed obj = null;
				try {
					obj = mapper.readValue(d.getData(), Feed.class);
				} catch (JsonParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (JsonMappingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return obj;
			} else {
				return null;
			}
		}
	}


	public void deleteFeed(String feedId) {
		// TODO Auto-generated method stub
		
	}

	

}
